<?php
/**
 * Creates file browsing option for admin.
 * 
 * Using:
 * Create fileBrowser popup file. Lets say its on http://mySite/fileBrowser.php
 * fileBrowser.php contents should contain these lines: (Offcourse it must start Dom framework!)
 * <code> 
 * $manager = new DomFgFileBrowserPopUp();
 * $manager->display();
 * </code>
 * 
 * Now set fileBrowserUrl to http://mySite/fileBrowser.php and youre done!
 * 
* @author Oliver Leisalu, Inditel Meedia
* @package DomFg
* @subpackage Input
*/
class DomFgFileBrowser extends DomFgInput {
	
	/**
	 * Where filebrowser is located.
	 *
	 * @var String
	 */
	public $fileBrowserUrl;
	/**
	 * Root path from where files are shown
	 *
	 * @var String
	 */
	public $rootPath;
	/**
	 * Values: 
	 * File extensions that are allowed.
	 * Magical:
	 * __allFiles - allows selecting all files
	 * __folders - allows selecting folders.
	 *
	 * @var unknown_type
	 */
	private $allowedTypes = array('__allFiles'=>true);
	
	const SESSION_VAR = 'DomFg_fileBrowser';
	
	public function __construct( $name = NULL ) {
		parent::__construct( $name );
	}

	public function fileBrowserUrl( $url ) {
		$this->fileBrowserUrl = $url;
	}
	
	public function rootPath( $rootPath ) {
		$this->rootPath = $rootPath;
	}
	
	public function allowedTypes( array $values ) {
		$this->allowedTypes = array();
		foreach( $values as $key => $type ) {
			if( is_string($type) ) 
				$this->allowedTypes[$type] = true;
			else
				$this->allowedTypes[$key] = (bool)$type;
		}
		return $this;
	}

	/**
	* @return Array where 0 is full tmp_name and 1 is name
	*/
	public static function parsePost( $name, &$post ) {
		$post = stripslashes($post);
		$fileName = array_pop(explode('/',$post));
		return array( $_SESSION[self::SESSION_VAR][$name]['rootPath'] . $post, $fileName );
	}
	
	public function prepare() {
		$ses = &$_SESSION[self::SESSION_VAR][$this->name];
		$ses = array();
		$ses['rootPath'] = $this->rootPath;
		$ses['fileBrowserUrl'] = $this->fileBrowserUrl;
		$ses['templateUrl'] = DomFg::getTemplateUrl();
		$ses['allowedTypes'] = $this->allowedTypes;
	}
	
	public function render() {
		$this->prepare();
		$renderer = $this->getRenderer();
		$renderer->assign('input', $this );
		return $renderer->fetch('Input/FileManager.html');
	}
	

}

/**
 * This is used by DomFgFileBrowser! This is not input field!
 * 
 * @author Oliver Leisalu, Inditel Meedia
 * @package DomFg
 * @subpackage Input
 */
class DomFgFileBrowserPopUp {
	
	private $fileBrowserUrl;
	
	private $rootPath;
	
	private $templateUrl;
	
	private $allowedTypes = array();
	
	public function __construct() {
		
		$ses = &$_SESSION[DomFgFileBrowser::SESSION_VAR][$_GET['field']];
		
		if( isset($_SESSION[DomFgFileBrowser::SESSION_VAR][$_GET['field']]) === false )
			die('Restricted access!');
		
		$this->fileBrowserUrl = $ses['fileBrowserUrl'];
		$this->rootPath = $ses['rootPath'];
		$this->templateUrl = $ses['templateUrl'];
		$this->allowedTypes = $ses['allowedTypes'];
	
		// if path is not set by get use last used.
		if( $_GET['path'] == '')
			$_GET['path'] = $_SESSION[DomFgFileBrowser::SESSION_VAR]['lastPath'];
		
		// some security checks
		$_GET['path'] = str_replace('/../','',$_GET['path']);
		$_GET['path'] = str_replace('\..\\','',$_GET['path']);
		if( substr($_GET['path'],0,2) == '..') $_GET['path'] = '';
		
		$_GET['path']  = stripslashes($_GET['path']);
		
		// if path doesn't exist, don't use it.
		if( !file_exists( $this->rootPath . $_GET['path'] ) )
			$_GET['path'] = '';
		
		// memorize only if is dir
		if( is_dir( $this->rootPath . $_GET['path'] ) && $_GET['choose'] != 1 )
			$_SESSION[DomFgFileBrowser::SESSION_VAR]['lastPath'] = $_GET['path'];
	}
	
	
	public function getUrl( $add = '' ) {
		return $this->fileBrowserUrl.'?field='.$_GET['field'].$add;
	}
	
	private function getCurrentPath() {
		return $this->rootPath . $_GET['path'];
	}
	
	private function getFilesHtml() {
		
		//-----------------
		// if clicked file then update form and close window
		if( is_file($this->getCurrentPath()) or $_GET['choose'] == 1) {
			return '
			<script type="text/javascript">
				window.opener.document.getElementById(\''.$_GET['field'].'\').value=\''.addslashes($_GET['path']).'\'; 
				window.close()
			</script>';
		}
		
		//-----------------
		// generate files list
		$dirs = array();
		$files = array();
		
		foreach( glob( $this->getCurrentPath().'*' ) as $path ) {
			$relativePath = str_replace($this->rootPath, '', $path);
			$file = array();
			$file['path'] = $path;
			$file['name'] = array_pop(explode('/', $path));
			$file['ext'] = is_dir($path) ? '' : array_pop(explode('.', $path));
			$file['icon'] = '<img src="'.$this->templateUrl.'Input/fileBrowser/types/'.($file['ext'] ? $file['ext'] : 'folder').'.png"/>';
			$file['id'] = $relativePath.(is_dir($path) ? '/' : '');
			$file['size'] = filesize( $path );
			$file['changedTime'] = date('d-m-Y H:i:s',filemtime( $path ));
			
			is_dir($path) ? $dirs[strtolower($file['name'])] = $file : $files[strtolower($file['name'])] = $file;
		}
		natksort($dirs );
		natksort($files);
		
		
		//-----------------
		// Add back button
		$files = array_merge( $dirs, $files );
		if( $_GET['path'] != '' && $_GET['path'] != '/' ) {
			$oneBackPath = explode('/',$_GET['path']);
			array_pop($oneBackPath);
			array_pop($oneBackPath);
			$oneBackPath = implode('/',$oneBackPath).'/';
			array_unshift( $files, array(
				'name'=>'Tagasi...',
				'back' => true,
				'id'=>$oneBackPath, 
				'link'=>$this->getUrl('&path='),
				'icon'=>'<img src="'.$this->templateUrl.'Input/fileBrowser/types/back.png"/>'
				) );
		}
		
		
		//-----------------
		// make panel
		function filesizeInfo($fs) { 
			$bytes = array('B', 'KB', 'MB', 'GB', 'TB'); 
			for ($i = 0; $fs > 999; $i++) $fs /= 1024; 
	 		return ceil($fs).$bytes[$i]; 
		} 

		function chooseFile( &$row, $i, DomFgFileBrowserPopUp $controller, array $allowedTypes) {
			if( $row['back'] ) {
				return '';
			} else if( $allowedTypes[strtolower($row['ext'])] or $allowedTypes['__allFiles'] && $row['ext'] != '' or $allowedTypes['__folders'] && $row['ext'] == '' ) {
				return '<a href="'.$controller->getUrl('&path='.$row['id'].'&choose=1').'">Vali</b>';
			} else {
				return '';
			}
		}
		
		$panel = array(
			'title'  => 'Failid',
			'items' => array(
				array(
					'type' => 'grid',
					'source' => new DomFgDataSource( $files,99999 ),
					'fields' => array(
						array('key'=>'icon','title'=>'Nimi', 'colspan'=>2, 'width'=>20),
						array('key'=>'name', 'link'=>$this->getUrl('&path='), 'width'=>200),
						array('key'=>'size','handler'=>'filesizeInfo','title'=>'Suurus', 'width'=>40),
						array('key'=>'changedTime','title'=>'Viimati muudetud', 'width'=>130),
						array('handler'=>'chooseFile', 'handlerArgs' => array( $this, $this->allowedTypes), 'title'=>'', 'width'=>40),
					),
				),
			),
		);
		return DomFg::render( $panel );
	}
	
	public function fetch() {
		return '
			<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
			<html xmlns="http://www.w3.org/1999/xhtml">
			<head>
			<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
			<title>Failihaldur</title>
			<style type="text/css">
			<!--
			div.fg_header { display:none; }
			-->
			</style>
			'.DomFg::renderHead().'
			</head>
			
			<body>
			'.DomFg::renderHeader().
			$this->getFilesHtml().
			DomFg::renderFooter().
			'</body></html>';
	}
	
	
	public function display() {
		echo $this->fetch();
	}
}
?>